import { isObject, isReservedTag } from "../utils";

export function createElement(vm, tag, data = {}, ...children) {
  //   console.log(vm, tag, data, children);
  // 如果tag是一个组件， 应该渲染一个组件的vnode
  // console.log(tag);
  if (isReservedTag(tag)) {
    return vnode(vm, tag, data, data.key, children, undefined);
  } else {
    // console.log(tag);
    const Ctor = vm.$options.components[tag];
    return createComponent(vm, tag, data, data.key, children, Ctor);
  }
}

// 创建组件的虚拟节点， 为了区分组件和元素， data.hook / componentOptions
function createComponent(vm, tag, data, key, slot, Ctor) {
  // 组件的构造函数
  // console.log(Ctor);
  if (isObject(Ctor)) {
    Ctor = vm.$options._base.extend(Ctor);
  }

  data.hook = {
    init(vnode) {
      let vm = (vnode.componentInstance = new Ctor({ _isComponent: true })); // new Sub() , 会用此选项和组件的配置进行合并
      console.log(vm);
      // debugger;
      vm.$mount(); // 组件挂载完成后， 会在vm.$el ==> <button>
      // vnode.componentInstance.$el ==> <button>
    },
  };
  // console.log(Ctor);
  return vnode(vm, `vue-component-${tag}`, data, key, undefined, undefined, {
    Ctor,
    slot,
  });
}

export function createTextElement(vm, text) {
  //   console.log(vm, text);
  return vnode(vm, undefined, undefined, undefined, undefined, text);
}

function vnode(vm, tag, data, key, children, text, componentOptions) {
  return {
    vm,
    tag,
    data,
    key,
    children,
    text,
    //   ...
  };
}
